package com.taoyibao.hongcanting.utils;

import java.util.ArrayList;
import java.util.Calendar;

/**
 * @author TangAnna
 * @description: 阴历算法的工具类
 * @date :${DATA} 10:45
 */
public class LunarDateUtils {

    private static final String YEAR = "年";
    private static final String RUN_MONTH = "润";

    /**
     * 正常月份数据源
     */
    private final static String monthData[] = {"正月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "腊月"};

    private final static String chineseNumber[] = {"一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二"};
    // 农历部分假日
    private final static String[] lunarHoliday = new String[]{"0101 春节", "0115 元宵", "0505 端午", "0707 情人", "0715 中元", "0815 中秋", "0909 重阳",
            "1208 腊八", "1224 小年", "0100 除夕"};

    final static long[] lunarInfo = new long[]{ //
            0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, //
            0x055d2, 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, //
            0x095b0, 0x14977, 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, //
            0x09570, 0x052f2, 0x04970, 0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, //
            0x186e3, 0x092e0, 0x1c8d7, 0x0c950, 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, //
            0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, 0x06ca0, 0x0b550, 0x15355, 0x04da0, //
            0x0a5d0, 0x14573, 0x052d0, 0x0a9a8, 0x0e950, 0x06aa0, 0x0aea6, 0x0ab50, 0x04b60, //
            0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, 0x096d0, 0x04dd5, //
            0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b5a0, 0x195a6, 0x095b0, //
            0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, //
            0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, //
            0x092e0, 0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, //
            0x092d0, 0x0cab5, 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, //
            0x15176, 0x052b0, 0x0a930, 0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, //
            0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, 0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0, //
            0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, 0x0b5a0, 0x056d0, 0x055b2, 0x049b0, //
            0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0};
    private int mCurrentYear; //当前年份
    private int mCurrentMonth;//当前月份
    private int mCurrentDay;//当前日期

    private ArrayList<Integer> mIntMonth = new ArrayList<>();

    public LunarDateUtils() {
        //初始化当前年月日
        Calendar c = Calendar.getInstance();
        mCurrentYear = c.get(Calendar.YEAR);
        //Calendar获取到的月份从0开始计算  实际值要加一
        mCurrentMonth = c.get(Calendar.MONTH) + 1;
    }

    /**
     * 获取年的数据
     */
    public ArrayList<String> getYearData(int start) {
        ArrayList<String> list = new ArrayList<>();
        for (int i = start; i > 1800; i--) {
            list.add(String.valueOf(i) + YEAR);
        }
//        mDefaultYearIndex = list.indexOf(mCurrentYear + YEAR);
        return list;
    }

    /**
     * 获取月份
     *
     * @param year 当前年份
     */
    public ArrayList<String> getMonthData(int year) {
        ArrayList<String> list = new ArrayList<>();
        for (int i = 0; i < monthData.length; i++) {
            list.add(monthData[i]);
            mIntMonth.add(i + 1);//记录数字的月份
        }
        if (leapMonth(year) != 0) {//没有闰月
            int runMonth = leapMonth(year);//润月份
            list.add(runMonth, RUN_MONTH + monthData[runMonth - 1]);
            mIntMonth.add(runMonth, runMonth);//记录数字的月份
        }
        return list;
    }

    /**
     * 获取对应的天数
     *
     * @param year
     * @param monthIndex 阴历月分集合的下标
     * @return
     */
    public ArrayList<String> getDayData(int year, int monthIndex) {
        ArrayList<String> list = new ArrayList<>();
        int totalDay = monthDays(year, monthIndex);
        for (int i = 1; i < totalDay + 1; i++) {
            list.add(getChinaDayString(i));
        }
        return list;
    }

    /**
     * 传回农历 y年闰哪个月 1-12 , 没闰传回 0
     *
     * @param y 年份
     * @return 该年闰月的月数
     */
    private int leapMonth(int y) {
        return (int) (lunarInfo[y - 1900] & 0b1111);
    }

    /**
     * 传回农历 y年m月的总天数
     *
     * @param y 年份
     * @param m 月份
     * @return 该月份的总天数
     */
    private int monthDays(int y, int m) {
        if ((lunarInfo[y - 1900] & (0x10000 >> m)) == 0)
            return 29;
        else
            return 30;
    }

    /**
     * 阳历转阴历日
     *
     * @param day
     * @return
     */
    private String getChinaDayString(int day) {
        String chineseTen[] = {"初", "十", "廿", "三"};
        int n = day % 10 == 0 ? 9 : day % 10 - 1;
        if (day > 30)
            return "";
        if (day == 10)
            return "初十";
        else
            return chineseTen[day / 10] + chineseNumber[n];
    }

}
